﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using Labthink.PCSoft.UniversalHost4.DataAccess;
using Labthink.PCSoft.UniversalHost4.Model;
using Labthink.PCSoft.UniversalHost4.Model.Query;
using Labthink.PCSoft.UniversalHost4.Utility;

namespace Labthink.PCSoft.UniversalHost4.UserControls
{
    public partial class UcOperationLog
    {
        private NotifyManager _notify;

        public UcOperationLog()
        {
            DataContext = this;
            InitializeComponent();
            btnSearch.Focus();
            dpEnd.DpPicker.SelectedDate = DateTime.Now.AddDays(1);
            dpStart.DpPicker.SelectedDate = DateTime.Now.AddMonths(-3);
            pager.OnPageIndexChanged += (sender, args) =>
            {
                PagingInfo r = GetLogs(pager.PageIndex);
                UpdatePager(r);
            };
        }

        private const int PageSize = 10;

        public ObservableCollection<OperateLog> Logs { get; } =
            new ObservableCollection<OperateLog>(new List<OperateLog>());

        private QueryLog _ql;

        public string Title { get; set; } = LanguageManager.GetLanguageValue("OpLogWindowTitle");

        public string PermissionCode { get; set; } = "Per_OperationLog";

        private PagingInfo GetLogs(int pageIndex)
        {
            _ql.PageIndex = pageIndex;
            return GetLogs();
        }

        private void UpdatePager(PagingInfo pi)
        {
            pager.TotalItemCount = pi.TotalItemCount;
            pager.TotalPageCount = pi.TotalPageCount;
        }

        void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            //e.Row.Header = $"{e.Row.GetIndex() + 1,2}";
        }

        private void Control_Loaded(object sender, RoutedEventArgs e)
        {
            if (DesignerProperties.GetIsInDesignMode(this))
            {
                return;
            }

            var w = Window.GetWindow(this);
            _notify = NotifyManager.InstanceManager(w);

            LoadLogs();
        }

        public void LoadLogs()
        {
            LoadData.Visibility = Visibility.Collapsed;
            pager.PageIndex = 1;
            pager.ItemCountPerPage = PageSize;
            if (!dpEnd.DpPicker.SelectedDate.HasValue) dpEnd.DpPicker.SelectedDate = DateTime.Now.AddDays(1);
            if (!dpStart.DpPicker.SelectedDate.HasValue) dpStart.DpPicker.SelectedDate = DateTime.Now.AddMonths(-3);
            _ql = new QueryLog
            {
                PageIndex = 1,
                PageCount = PageSize,
                Start = dpStart.DpPicker.SelectedDate.Value,
                End = dpEnd.DpPicker.SelectedDate.Value,
                IsAdmin = Common.CurrentUser.Role < 3,
                Type = null,
                Content = null,
            };

            //if (!_ql.IsAdmin)
            //{
            //    txtUsername.Value = Common.CurrentUser.LoginName;
            //    txtUsername.IsEnabled = false;
            //    _ql.User = txtUsername.Value;
            //}

            PagingInfo r = GetLogs();
            dgLogs.ItemsSource = Logs;
            UpdatePager(r);
        }

        private PagingInfo GetLogs()
        {
            ShowLoading();

            Logs.Clear();
            dgLogs.Items.Refresh();
            PagedList<OperateLog> plo = LogRepository.GetLogs(_ql.User, _ql.IsAdmin, _ql.Type, _ql.Start, _ql.End, _ql.Content,
                _ql.PageIndex, _ql.PageCount);

            if (plo.InnerList == null || !plo.InnerList.Any())
            {
                HideLoading();
                return new PagingInfo(0, 0);
            }

            List<OperateLog> logs = plo.InnerList.ToList();
            Logs.Clear();
            foreach (OperateLog log in logs)
            {
                Logs.Add(log);
            }

            HideLoading();

            return new PagingInfo(plo.TotalCount, plo.PageCount);
        }

        private void BtnSearch_OnClick(object sender, RoutedEventArgs e)
        {
            Logs.Clear();
            UpdatePager(new PagingInfo(0, 0));

            _ql.PageIndex = 1;
            _ql.User = txtUsername.Value;
            _ql.Start = dpStart.DpPicker.SelectedDate ?? DateTime.MinValue;
            _ql.End = dpEnd.DpPicker.SelectedDate ?? DateTime.MaxValue;
            _ql.Content = txtContent.Value;

            PagingInfo r = GetLogs();
            pager.PageIndex = 1;
            UpdatePager(r);
        }

        private void BtnReset_OnClick(object sender, RoutedEventArgs e)
        {
            txtUsername.Value = "";
            txtContent.Value = "";
            dpStart.DpPicker.SelectedDate = null;
            dpEnd.DpPicker.SelectedDate = null;
            dpStart.DpPicker.Text = null;
            dpEnd.DpPicker.Text = null;
            pager.PageIndex = 1;

            _ql.User = "";
            _ql.Content = null;
            _ql.Start = DateTime.MinValue;
            _ql.End = DateTime.MaxValue;
            _ql.PageIndex = 1;

            _notify.ShowSuccess(LanguageManager.GetLanguageValue("ActionSuccess"));
            PagingInfo r = GetLogs();
            UpdatePager(r);
            txtUsername.Focus();
        }

        private void ShowLoading()
        {
            LoadData.Visibility = Visibility.Visible;
        }

        private void HideLoading()
        {
            LoadData.Visibility = Visibility.Collapsed;
        }

        private void LoadData_OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            var isEnabled = sender is Loading loading && loading.Visibility == Visibility.Collapsed;

            var controls = new List<Control>
            {
                btnSearch,
                btnReset,
                pager,
            };

            foreach (var c in controls)
            {
                c.IsEnabled = isEnabled;
            }
        }

        private void BtnPrint_OnClick(object sender, RoutedEventArgs e)
        {
            ShowLoading();
            var logs = LogRepository.GetLogs(_ql.User, _ql.IsAdmin, _ql.Type, _ql.Start, _ql.End, _ql.Content,
                _ql.PageIndex, _ql.PageCount);
            var ds = new DataSet();
            var dt = ds.Tables.Add("Log");
            var t = typeof(OperateLog);
            foreach (PropertyInfo pi in t.GetProperties())
            {
                dt.Columns.Add(pi.Name, pi.PropertyType);
            }

            foreach (OperateLog log in logs.InnerList)
            {
                var dr = dt.NewRow();
                foreach (var pi in t.GetProperties())
                {
                    dr[pi.Name] = pi.GetValue(log, null);
                }

                dt.Rows.Add(dr);
            }

            if (logs.PageCount > 1)
            {
                var tmpIndex = _ql.PageIndex;
                for (int i = 2; i <= logs.PageCount; i++)
                {
                    _ql.PageIndex = i;
                    logs = LogRepository.GetLogs(_ql.User, _ql.IsAdmin, _ql.Type, _ql.Start, _ql.End, _ql.Content,
                _ql.PageIndex, _ql.PageCount);
                    foreach (var log in logs.InnerList)
                    {
                        var dr = dt.NewRow();
                        foreach (PropertyInfo pi in t.GetProperties())
                        {
                            dr[pi.Name] = pi.GetValue(log, null);
                        }

                        dt.Rows.Add(dr);
                    }
                }
                _ql.PageIndex = tmpIndex;
            }

            var info = ds.Tables.Add("Info");
            info.Columns.Add("Title", typeof(string));
            info.Columns.Add("Printer", typeof(string));
            info.Columns.Add("UserId", typeof(string));
            info.Columns.Add("Content", typeof(string));
            info.Columns.Add("LogTime", typeof(string));
            var row = info.NewRow();
            row["Title"] = LanguageManager.GetLanguageValue("OpLogWindowTitle");
            row["Printer"] = Common.CurrentUser.UserName + " " + DateTime.Now.ToShortDateString();
            row["UserId"] = LanguageManager.GetLanguageValue("UserID");
            row["Content"] = LanguageManager.GetLanguageValue("Content");
            row["LogTime"] = LanguageManager.GetLanguageValue("OperationTime");
            info.Rows.Add(row);
            HideLoading();
            var frm = new FrmLogPrint { DsData = ds };
            frm.ShowDialog(Application.Current.MainWindow);
        }

        private void _triggerButtonsStatus(bool status)
        {
            btnPrint.IsEnabled = status;
            btnReset.IsEnabled = status;
            btnSearch.IsEnabled = status;
            if (status) LoadData.Visibility = Visibility.Collapsed;
            else LoadData.Visibility = Visibility.Visible;
        }
    }
}
